package com.kaifamiao.uploader.service.impl;

import com.kaifamiao.uploader.dao.ChunkRepository;
import com.kaifamiao.uploader.entity.Chunk;
import com.kaifamiao.uploader.entity.FileInfo;
import com.kaifamiao.uploader.service.ChunkService;
import com.kaifamiao.uploader.service.FileInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;

@Service
@Slf4j
public class ChunkServiceImpl implements ChunkService {

    @Autowired
    private ChunkRepository chunkRepository;
    @Autowired
    private FileInfoService fileInfoService;
    @Value("${upload.path}")
    private String filePath;


    @Override
    public List<Chunk> findChunksByFileIdentifier(String identifier) {
        return chunkRepository.findAllByIdentifierOrderByChunkIndex(identifier);
    }

    @Override
    public void save(Chunk chunk) {
        chunkRepository.save(chunk);
    }

    @Override
    @Transactional
    public String merge(String iderntifier) throws IOException {
        // 查询该文件的所有分片
        List<Chunk> chunks = chunkRepository.findAllByIdentifierOrderByChunkIndex(iderntifier);
        // 获取文件类型
        String type = chunks.get(0).getFilename().substring(chunks.get(0).getFilename().lastIndexOf(".") + 1);
        Path targetFile = Files.createFile(Path.of(filePath, chunks.get(0).getIdentifier() + "." + type));
        if (targetFile.getParent().toFile().exists()){
            targetFile.getParent().toFile().mkdirs();
        }
        // 合并文件
        chunks.forEach((chunk) -> {
            // id/id_index
            String pathStr = chunk.getIdentifier() + File.separator + chunk.getIdentifier() + "_" + chunk.getChunkIndex();
            File f = new File(filePath, pathStr);
            if (!f.exists()) {
                throw new RuntimeException("文件分片不存在");
            }
            Path path = f.toPath();
            try {
                // 合并文件
                Files.write(targetFile, Files.readAllBytes(path), StandardOpenOption.APPEND);
                // 删除分片
                Files.delete(path);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        // 删除文件夹
        File folder = new File(filePath, chunks.get(0).getIdentifier());
        Files.delete(folder.toPath());

        // 访问路径
        String path = "/upload/" + chunks.get(0).getIdentifier() + "." + type;
        // 保存文件记录
        FileInfo fileInfo = new FileInfo();
        fileInfo.setFilename(chunks.get(0).getFilename());
        fileInfo.setIdentifier(chunks.get(0).getIdentifier());
        fileInfo.setTotalSize(Integer.valueOf(chunks.size()).longValue());
        fileInfo.setLocation(path);
        fileInfo.setType(type);

        fileInfoService.save(fileInfo);

        // 删除分片记录
        chunkRepository.removeByIdentifier(fileInfo.getIdentifier());

        return path;

    }

    @Override
    public void uplaod(Chunk chunk, MultipartFile file) throws IOException {
        // id/id_index
        String pathStr = chunk.getIdentifier() + File.separator + chunk.getIdentifier() + "_" + chunk.getChunkIndex();
        log.debug("文件 {} 写入成功, id:{}", chunk.getFilename(), chunk.getIdentifier());
        File f = new File(filePath, pathStr);
        if (!f.getParentFile().exists()) {
            f.getParentFile().mkdirs();
        }

        file.transferTo(f);
        chunk.setRelativePath(pathStr);
        save(chunk);
    }
}
